闲话 22.10.27

闲话

所以就算比赛我写杂题的速度也是两道吗
当然主要是赛后三十分钟改完两道题的原因(

所以今天终于换智能推荐了
【模板】二分图最大匹配【模板】最大流

?没什么好写的
那就写明天的闲话吧

对了我似乎该把闲话归归类了

杂题

AT S8PC3 G

给定 \(n,m\),求斐波那契数列 \(n\) 阶前缀和的第 \(m\) 项。

\(n\le 2\times 10^5, m \le 10^{18}\)

不是多项式题。

如果把 \(n,m\) 的数据范围换一下这就是大水题了。答案即为

\[[x^m]\frac {x}{(1-x)^n(1-x-x^2)} \]

随便写点啥都能过吧。

然后解决原问题。这次我们没法简单地通过生成函数得到系数了。当然可能有理展开定理能做,但我没细想。

考虑一手通过通项公式求前缀和表达式。这部分 dirty work,具体看这里
于是我们有一个

\[\sum_{i=1}^n f_i = f_{n+2} - f_2 \]

再化一步,得到

\[\sum_{i=1}^n f_i = f_{n+2} - \binom{n-1}{0} f_2 \]

\(f\)\(n\) 阶前缀和的第 \(m\) 项为 \(d_{n,m}\)。我们断言,有

\[d_{n,m} = f_{m+2(n-1)} - \sum_{i=0}^{n-1}\binom{m+i-1}{i} f_{2(n-i-1)} \]

证明:
采用数学归纳法。假设对于任意正整数 \(k < n\) 有任意 \(d_{k,m}\) 满足此公式,我们要证明对于任意 \(d_{n,m}\) 也满足。

\[\begin{aligned} d_{n,m} &= \sum_{i=1}^m d_{n-1,i} \\ &= \sum_{i=1}^m \left( f_{i+2(n-2)} - \sum_{j=0}^{n-2}\binom{i+j-1}{j} f_{2(n-j-2)} \right) \\ &= \sum_{i=1}^m f_{i+2(n-2)} - \sum_{i=1}^m \sum_{j=0}^{n-2}\binom{i+j-1}{j} f_{2(n-j-2)} \\ &= f_{m+2(n-2)+2} - f_{2} - \sum_{i=1}^{2(n-2)} f_{i} - \sum_{i=1}^m \sum_{j=0}^{n-2}\binom{i+j-1}{j} f_{2(n-j-2)} \\ &= f_{m+2n-2} - f_{2} - f_{2n-2} + f_{2} - \sum_{j=0}^{n-2} \binom{n+j}{j+1} f_{2(n-j-2)} \\ &= f_{m+2n-2} - f_{2n-2} - \sum_{j=0}^{n-2} \binom{n+j}{j+1} f_{2(n-j-2)} \\ &= f_{m+2n-2} - \binom{n+0-1}{0}f_{2(n-0-1)} - \sum_{j=1}^{n-1} \binom{n+j-1}{j} f_{2(n-j-1)} \\ &= f_{m+2n-2} - \sum_{j=0}^{n-1} \binom{n+j-1}{j} f_{2(n-j-1)} \\ &= f_{m+2(n-1)} - \sum_{i=0}^{n-1}\binom{m+i-1}{i} f_{2(n-i-1)} \end{aligned}\]

证毕。还是很 dirty 的

当然有另一种不化式子的做法,直接生成函数卷出来这个式子。但是没有减号后面的具体形式,需要插出来系数。

啊 第三种是 Bostan-Mori 硬干

code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for (register int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define pre(i,a,b) for (register int i = (a), i##_ = (b) - 1; i > i##_; --i)
const int N = 5e5 + 10, mod = 998244353;
int n, m, fib[N], inv[N], ans;

struct mat {
    int a[2][2];
    mat() { memset(a, 0, sizeof a); };
    
    void I() { memset(a, 0, sizeof a); a[0][0] = a[1][1] = 1; }

    mat operator * (const mat & b) const {
        mat ret; memset(ret.a, 0, sizeof ret.a);
        rep(i,0,1) rep(j,0,1) rep(k,0,1) ret.a[i][j] = (ret.a[i][j] + 1ll * a[i][k] * b.a[k][j] % mod) % mod;
        return ret;
    }
} mt;

mat qp(mat a, int b) {
    mat ret; ret.I();
    while (b) {
        if (b & 1) ret = ret * a;
        a = a * a;
        b >>= 1;
    } return ret;
}

signed main() {
    cin >> n >> m;

    mt.a[0][0] = mt.a[0][1] = mt.a[1][0] = 1; 
    fib[1] = inv[1] = 1;
    rep(i,2,n<<1) fib[i] = (fib[i-1] + fib[i-2]) % mod;
    rep(i,2,n) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;

    ans = qp(mt, m + 2 * (n - 1)).a[0][1];
    for (int i(0), c(1); i < n; ++ i) {
        ans = (ans - 1ll * c * fib[2 * (n - i - 1)] % mod + mod) % mod;
        c = 1ll * (m + i) % mod * c % mod * inv[i + 1] % mod;
    } 

    cout << ans << endl;
}



P3600 随机数生成器

随机生成一个长度为 \(n\),值域为 \([1,x]\) 的数列,每次询问一个区间 \([l,r]\) 的最小值,最终答案为所有询问的最大值,求答案的期望。对 \(666623333\) 取模。

\(n, x, q \le 2000\)

如果一个区间被另一个区间完全包含,则包含别人的区间就没有用了,因为它的答案不会更优。
去重后只需要考虑区间有交的情况,且按左端点递增排序。

考虑整数期望公式:

\[E[x] = \sum_{i=1}^{\infty} i \times P[x=i] = \sum_{i=1}^{\infty} i \times \left(P[x \ge i] - P[x \ge i+1]\right) = \sum_{i=1}^{\infty} i \times P[x\ge i] \]

考虑如何计算 \(P[x\ge i]\)。我们发现,由于是算最小值,可以转化为 \(1 - P[x < i]\) 方便计算。由于答案是各区间最小值的最大值,那就是保证每个询问区间里都存在一个 \(x < i\) 的数。

转化区间和元素的关系,我们让元素去找区间。一个元素能覆盖一段区间,覆盖的概率为 \(p = \frac{i-1}x\)。我们令 \(lp[i]\) 为元素 \(i\) 能覆盖的区间中编号最小的编号,\(rp[i]\) 为最大编号。
\(f[i]\) 为必选值 \(i\),且 \(1\sim rp[i]\) 的所有区间都被覆盖的概率。设从 \(j<i\) 转移过来,由于都要被覆盖,则需要满足 \(rp[j] \ge lp[i]-1\)。又,需要考虑不需要覆盖前面部分的情况,有转移

\[f[i]=p\times \left(\sum_{rp[j]\ge lp[i]-1} f[j](1-p)^{i-j-1}+[lp[i]=1](1-p)^{i-1}\right) \]

最后值 \(i\) 对答案造成的贡献为

\[\sum_{rp[i] = q} f[i]\times (1-p)^{n-i} \]

计算即可。双指针优化 \(f\) 的计算,总复杂度 \(O(n^2)\)

听说 \(x\) 能开到 \(10^7\)。我不是很会做法。

code
// for (int j = 1; j <= m; ++ j) fac[i] = 1ll * fac[i-1] * i % mod;
#include <bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
    char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
    #define getchar getc
#endif
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = 0; while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f and (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }
#define rep(i,a,b) for (register int i(a), i##_((b) + 1); i < i##_; ++i)
#define pre(i,a,b) for (register int i(a), i##_((b) - 1); i > i##_; --i)
const int N = 3e5 + 10, mod = 666623333;
int n, x, q, ans, stk[N], top, lp[N], rp[N], f[N], inv[N];

struct itv {
	int l, r;
	bool operator < (const itv & b) const { if (l != b.l) return l < b.l; return r > b.r; }
} a[N];
int qp(int a, int b) { int ret = 1; while ( b ) { if (b & 1) ret = 1ll * ret * a % mod; a = 1ll * a * a % mod; b >>= 1;} return ret; }

signed main() {
    get(n, x, q); rep(i,1,q) get(a[i].l, a[i].r);
	sort(a+1, a+1+q);
	
	rep(i,1,q) {
		while (top and a[stk[top]].r >= a[i].r) -- top;
		stk[++top] = i;
	} q = top; rep(i,1,q) a[i] = a[stk[i]];

	for (int i(1), l(1), r(0); i <= n; ++ i) {
		while (r < q and a[r + 1].l <= i) ++ r;
		while (l <= r and a[l].r < i) ++ l;
		lp[i] = l, rp[i] = r;
	}

	rep(t,1,x) {
		int sum = 1, p = 1ll * (t - 1 + mod) * qp(x, mod - 2) % mod, np = (1 - p + mod) % mod;
		int invp = qp(np, mod - 2), nowp = 1;
		inv[0] = f[0] = 1; 
		rep(i,1,n) inv[i] = 1ll * inv[i-1] * invp % mod;
		for (int i(1), j(0); i <= n; ++ i) {
			while (j < i and rp[j] < lp[i] - 1) sum = (sum - 1ll * f[j] * inv[j] % mod + mod) % mod, ++ j;
			f[i] = 1ll * sum * nowp % mod * p % mod; nowp = 1ll * nowp * np % mod;
			sum = (sum + 1ll * f[i] * inv[i]) % mod; 
		}
		int tot = 0; nowp = 1;
		for (int i = n; i; -- i) {
			if (rp[i] != q) break;
			tot = (tot + 1ll * f[i] * nowp) % mod;
			nowp = 1ll * nowp * np % mod;
		}
		ans = (ans + 1 - tot + mod) % mod;
	}
	cout << ans << '\n';
}
posted @ 2022-10-27 17:16  joke3579  阅读(36)  评论(2编辑  收藏  举报